/* -----------------
* brief
* 1. this is code gen by tools
 */

package service

import (
	"errors"
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"github.com/mjiulee/lego"
	"saas_sys_base/common"
	. "saas_sys_base/modules/user/models"
	"saas_sys_base/sysconfig"
)

type UserServiceInterface interface {
	CheckToken(passToken string, timestamp string) (userwho *common.Who, loginuser *LoginUser,  err error)
	ThirdLogin(thirdUid int64) (*User, error)

}
var _ UserServiceInterface = (*UserService)(nil)
//var _ AccessTokenServer = (*DefaultAccessTokenServer)(nil)

type UserService struct {
	UserServiceInterface
	// add your model here
	tbUser User

	//wxUserService           WxUserService
	//webUserService           WebUserService
	//appTenantUserRelService AppTenantUserRelService
	//appTenantRelService AppTenantRelService
}

func (t *UserService) ListUser(keyword string, page, psize int, orderField, order string) ([]map[string]string, int64, error) {
	// 业务查询
	queryMap := map[string]interface{}{
		"table":  map[string]string{"table": "tb_user", "alias": "t1"},
		"fields": []string{"t1.*"},
		"join":   []map[string]string{
			// map[string]string{"table": "tb_xx as t2", "on": "t2.xid = t1.id"},
		},
		"where": []lego.QMapWhereField{
			{"t1.if_del", "=", 0, "AND", false},
		},
		"search": map[string]string{
			//"t1.id": req.Keyword,
		},
		"orders": []string{"t1.id asc"},
		"page": map[string]int{
			"page":  page,
			"psize": psize,
		},
	}

	if orderField != "" && order != "" {
		orderStr := fmt.Sprintf("t1.%s %s", orderField, order)
		queryMap["orders"] = []string{orderStr, "t1.cdate asc"}
	}

	return lego.QueryListByMap(queryMap)
}

/* 根据id获取记录
 * -----------------
 */
func (t *UserService) GetUserById(id int64) *User {
	return t.tbUser.RecodeById(id)
}

func (t *UserService) GetUserByWxUid(wxUid int64) *User {
	return t.tbUser.RecodeByWxUid(wxUid)
}

/* 添加
 * -----------------
 */
func (t *UserService) SaveUser(item2add *User) bool {
	return t.tbUser.AddRecode(item2add)
}

/* 删除(硬删除)*/
func (t *UserService) DelUserById(id int64) bool {
	return t.tbUser.DelRecodeById(id)
}

/* 更新
 * -----------------*/
func (t *UserService) UpdateUser(rc *User) bool {
	return t.tbUser.UpdateRecode(rc)
}

//以下是自定义函数
//统一的用户结构定义
type LoginUser struct {
	User *User
	WxUser  *WxUser
	WebUser  *WebUser

}




func GetUserIdFromToken(passToken string) (uid string, err error) {
	token, err := jwt.Parse(passToken, func(token *jwt.Token) (interface{}, error) {
		return []byte(sysconfig.SecretKey()), nil
	})

	if err != nil {
		return "", err
	}

	if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
		uid := string(claims["uid"].(string))
		return uid, nil
	} else {
		return "", err
	}
}

func (t *UserService) CheckToken(passToken string, timestamp string) (who *common.Who, user *LoginUser,  err error) {
	//需要在其子类中继承重写此函数
	return nil, nil , errors.New("NEED TO OVERRIDE THIS FUNCTION")
}

func (t *UserService) ThirdLogin(thirdUid int64) (*User, error) {
	//需要在其子类中继承重写此函数
	return nil , errors.New("NEED TO OVERRIDE THIS FUNCTION")
}

func (t *UserService) ListUserByApp(who common.Who, keyword string, page, psize int) ([]map[string]string, int64, error) {
	// 业务查询
	queryMap := map[string]interface{}{
		"table":  map[string]string{"table": "tb_user", "alias": "t1"},
		"fields": []string{"t1.*"},
		"join":   []map[string]string{
			// map[string]string{"table": "tb_xx as t2", "on": "t2.xid = t1.id"},
		},
		"where": []lego.QMapWhereField{
			//{"t1.if_del", "=", 0, "AND", false},
			{"t1.if_del", "=", 0, "AND", false},
			{"t1.tenant_id", "=", who.TenantId, "AND", false},
			{"t1.mini_app_id", "=", who.MiniAppId, "AND", false},
			{"t1.uid", "=", who.Uid, "AND", false},
		},
		"search": map[string]string{
			//"t1.id": req.Keyword,
		},
		"orders": []string{"t1.id asc"},
		"page": map[string]int{
			"page":  page,
			"psize": psize,
		},
	}
	return lego.QueryListByMap(queryMap)
}


func (t *UserService) SwitchCurrentTenant(userWho *common.Who, tid int64) (error) {
	if tid == 0 {
		return nil
	}//tid为0时，不更新，只记录切换到非平台租户

	user := t.GetUserById(userWho.Uid)
	if user == nil {
		return fmt.Errorf("Not found uid<%d>", userWho.Uid)
	}
	user.CurrentTid = tid
	isSuccess := t.UpdateUser(user)
	if isSuccess == false {
		return errors.New("switchCurrentTenant UpdateUser failed")
	}

	return nil
}